package com.dean.utils;

import com.dean.entity.SftpConnectInfo;
import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.Vector;

public class DeanSftpUtils {

    private static final Logger log = LoggerFactory.getLogger(DeanSftpUtils.class);

    public static void download(SftpConnectInfo conninfo,String localFilePath,String sftpFilePath){
        download(conninfo,localFilePath,sftpFilePath,false);
    }

    public static void download(SftpConnectInfo conninfo,String localFilePath,String sftpFilePath,boolean keepMtime){
        ChannelSftp channelSftp = null;
        try {
            channelSftp = getChannelSftp(conninfo);
            Vector<ChannelSftp.LsEntry> files = channelSftp.ls(sftpFilePath);
            // 需要知道sftp文件的上级目录
            String sftpDir = sftpFilePath.substring(0,sftpFilePath.lastIndexOf("/"));
            log.info("sftpDir:"+sftpDir);
            for (ChannelSftp.LsEntry file : files) {
                log.info("long name :{}",file.getLongname());
                String fileName = file.getFilename();
                log.info("file name:{}",file.getFilename());
               // log.info(sftpFilePath+fileName);
                channelSftp.get(sftpDir+"/"+fileName,localFilePath);
                if(keepMtime){
                    File localFile = new File(localFilePath+File.separator+fileName);
                    log.info("{}",localFile.lastModified());
                    long mtime = file.getAttrs().getMTime()*1000L;
                    log.info("mtime:{}",mtime);
                    localFile.setLastModified(mtime);
                    log.info("{}",localFile.lastModified());
                }

            }

        } catch (SftpException | JSchException e) {
            log.error(e.getMessage(),e);
            throw new RuntimeException(e.getMessage());
        } finally {
            disconnect(channelSftp);
        }
    }


    public static void upload(SftpConnectInfo conninfo,String localFilePath,String sftpFilePath){
        ChannelSftp channelSftp = null;
        try {
            channelSftp = getChannelSftp(conninfo);
            channelSftp.put(localFilePath,sftpFilePath);
        } catch (SftpException | JSchException e) {
            log.error(e.getMessage(),e);
            throw new RuntimeException(e.getMessage());
        } finally {
            disconnect(channelSftp);
        }
    }

    public static ChannelSftp getChannelSftp(SftpConnectInfo conninfo) throws JSchException {
        return getChannelSftp(getSession(conninfo));
    }

    public static Session getSession(SftpConnectInfo connectInfo) throws JSchException {
        JSch jSch = new JSch();
        Session session = null;
        jSch.addIdentity(connectInfo.getPrikeyFilePath());
        session = jSch.getSession(connectInfo.getUsername(),connectInfo.getHost(),connectInfo.getPort());
        session.setConfig("StrictHostKeyChecking","no");
        session.connect();
        return session;
    }

    public static ChannelSftp getChannelSftp(Session session) throws JSchException {
        ChannelSftp channelSftp =null;
        channelSftp =  (ChannelSftp) session.openChannel("sftp");
        channelSftp.connect();
        return channelSftp;
    }

    public static void disconnect(ChannelSftp channelSftp,boolean closeSession) {
        Session session = null;
        if(closeSession){
            try {
                session = channelSftp.getSession();
            } catch (JSchException e) {
                log.warn("当前sftp通道未获取到session：{}",e.getMessage(),e);
            }finally {
                disconnect(session,channelSftp);
            }
        }else{
            disconnect(session,channelSftp);
        }

    }

    public static void disconnect(ChannelSftp channelSftp){
        disconnect(channelSftp,true);
    }


    public static void  disconnect(Session session){
        disconnect(session,null);
    }

    public static void  disconnect(Session session,ChannelSftp channelSftp){
        Optional<ChannelSftp> sftpOpt = Optional.ofNullable(channelSftp);
        if(sftpOpt.isPresent()){
            sftpOpt.get().disconnect();
        }
        Optional<Session> sessionOpt = Optional.ofNullable(session);
        if(sessionOpt.isPresent()){
            sessionOpt.get().disconnect();
        }
    }


}
